package cn.admin.config.common.protocol;

import cn.admin.config.common.Revision;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class UserDataElement implements ProtocolElement {

    public String dataId;
    public Revision revision;
    public String[] clientId;
    private List<Swizzle> data = new LinkedList<>();
    private boolean needAck = true;

    private static final Logger LOG = LoggerFactory.getLogger(UserDataElement.class);

    public UserDataElement(String dataId,Revision rev) {
        if (dataId == null) {
            throw new IllegalArgumentException("dataId can't be null");
        } else {
            this.dataId = dataId;
            this.revision = rev == null ? Revision.UNINITIALIZED_REVISION : rev;
        }
    }


    public Revision getRevision() {
        return revision;
    }

    public boolean addDatum(Object datum) {
        return datum instanceof Swizzle ? this.data.add((Swizzle)datum) : this.data.add(new Swizzle(datum));
    }

    //TODO

    public void addData(List<?> data) {

        for (Object datum : data) {
            this.addDatum(datum);
        }

    }

    public String getDataId() {
        return this.dataId;
    }

    public List<Swizzle> getShelteredData() {
        return new ArrayList<>(this.data);
    }

    public static void extractShelteredData(List<Serializable> data) {
        for(int i = 0; i < data.size(); ++i) {
            Serializable datum = data.get(i);
            if (datum instanceof Swizzle) {
                try {
                    datum = (Serializable) ((Swizzle)datum).extract();
                    if (datum == null) {
                        LOG.info("[Data] Null datum is removed.");
                    }
                } catch (Exception var4) {
                    LOG.warn("[Data] Failed to deserialize the datum due to " + var4);
                }

                if (datum != null) {
                    data.set(i, datum);
                } else {
                    data.remove(i);
                    --i;
                }
            }
        }

    }

    public boolean needAck() {
        return this.needAck;
    }

    public void setNeedAck(boolean needAck) {
        this.needAck = needAck;
    }

    @Override
    public ProtocolElementUid uid() {
        return ProtocolElementUid.ELEMENT_USER_DATA;
    }
}
